﻿/*
 Copyright (c) 2009 Alvin Cho (alvincho@risklib.com)
 Copyright (c) 2009 RiskLib.com
 
 This file is part of RiskLib.NET Project. See http://www.risklib.net for more information.
 
 RiskLib.NET is an open source project. Using of RiskLib.NET is free of charge.
 It is distributed under GNU General Public License version 2 (GPLv2).
 GPLv2 can be found at http://www.risklib.net/risklib/license.
 
 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.
*/
using System;
using System.Collections.Generic;
using System.Text;

namespace RiskLib
{
    public interface IIssuer
    {
        string IssuerName { get; set; }
        string IssuerWebSite{get;set;}
        string IssuerISIN{get;set;}
    }
    public interface IStandardSecurity
    {
        string ISIN{get;set;}
    }
    public interface IListed
    {
        string ListedExchange{get;set;}
    }
    public interface IEquity:IIssuer,IListed,IStandardSecurity
    {
    }
    public interface IExpirable
    {
        DateTime ExpiryDate{get;set;}
    }

    public interface IDerivativeSingleUnderler
    {
        IProduct Underlyer{get;set;}
    }
    public interface IDerivativeMultipleUnderlyer
    {
        List<IProduct> UnderLyerCodes{get;set;}
    }
    public interface IFuture : IExpirable, IDerivativeSingleUnderler
    {
    }
    public interface IOption:IExpirable
    {
        double Strike{get;set;}
    }

    public interface IFixedIncome
    {
    }
    public interface IBond
    {
        double Coupon{get;set;}
        int PaymentFrequencyPerYear{get;set;}
        int CouponFrequencyPerYear{get;set;}
    }

    public interface IInterestRate
    {
    }

    public interface IProductCode:IComparable
    {
        string ProductCode{get;set;}
        string GetProductCode(ProductCodeTypeEnum codeType);
        
    }
    public class SimpleProductCode:IProductCode
    {
        public SimpleProductCode(string code)
        {
            productCode = code;
        }
        string productCode;
        #region IProductCode 成員

        public string ProductCode
        {
            get
            {
                return productCode;
            }
            set
            {
                productCode = value;
            }
        }

        public string GetProductCode(ProductCodeTypeEnum codeType)
        {
            return productCode;
        }

        #endregion

        public override string ToString()
        {
            return productCode.ToString();
        }
        #region IComparable 成員

        public int CompareTo(object obj)
        {
            return this.ToString().CompareTo(obj.ToString());
        }

        #endregion
    }

    public interface IProduct:IProductCode
    {
        List<FieldNameEnum> FundamentalFields { get; set; }
        List<FieldNameEnum> HistoricalFields { get; set; }
    }
    public interface IHasHistoricalData
    {
        HistoricalDataList GetHistoricalData(DateTime startDate, DateTime endDate);
        HistoricalDataList GetHistoricalReturn(DateTime startDate, DateTime endDate);
    }
    public abstract class AbstractProduct:IProduct
    {
        public AbstractProduct(IProductCode code):this(code,new List<FieldNameEnum>(),new List<FieldNameEnum>())
        {
        }
        public AbstractProduct(IProductCode code, List<FieldNameEnum> fundamentalFieldList, List<FieldNameEnum> historicalFieldList)
        {
            productCode=code;
            fundamentalFields.AddRange(fundamentalFieldList);
            historicalFields.AddRange(historicalFieldList);
        }
        protected IProductCode productCode;

        protected List<FieldNameEnum> fundamentalFields = new List<FieldNameEnum>() 
        {
            FieldNameEnum.EnglishName, FieldNameEnum.Currency, FieldNameEnum.ChineseName 
        };
        protected List<FieldNameEnum> historicalFields = new List<FieldNameEnum>() 
        { 
            FieldNameEnum.OpenPrice, FieldNameEnum.HighPrice, FieldNameEnum.LowPrice, FieldNameEnum.ClosePrice, FieldNameEnum.DailyChange, FieldNameEnum.Volume 
        };

        protected FundamentalDataList fundamentalData = new FundamentalDataList();
        #region IProduct 成員

        public string ProductCode
        {
            get
            {
                return productCode.ProductCode;
            }
            set
            {
                productCode.ProductCode = value;
            }
        }
        public string GetProductCode(ProductCodeTypeEnum codeType)
        {
            return productCode.GetProductCode(codeType);
        }

        public List<FieldNameEnum> FundamentalFields
        {
            get
            {
                return fundamentalFields;
            }
            set
            {
                fundamentalFields = value;
            }
        }

        public List<FieldNameEnum> HistoricalFields
        {
            get
            {
                return historicalFields;
            }
            set
            {
                historicalFields = value;
            }
        }

        #endregion

        public override string ToString()
        {
            return productCode.ToString();
        }
        #region IComparable 成員

        public int CompareTo(object obj)
        {
            return this.ToString().CompareTo(obj.ToString());
        }

        #endregion
    }
    [Serializable]
    public class SimpleProduct : AbstractProduct
    {
        public SimpleProduct(string code):this(new SimpleProductCode(code))
        {
        }
        public SimpleProduct(IProductCode code)
            : base(code)
        {
        }
    }
}
